﻿using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System.Collections.Generic;
using System.Linq;
using System.Text;

[Generator]
public class DebouncerGenerator : IIncrementalGenerator
{
    public void Initialize(IncrementalGeneratorInitializationContext context)
    {
        // 1. 筛选目标类：名为"DataTracker"的静态类
        var classDeclarations = context.SyntaxProvider
            .CreateSyntaxProvider(
                predicate: static (s, _) => IsTargetClass(s),
                transform: static (ctx, _) => GetClassDeclaration(ctx))
            .Where(static c => c is not null);

        // 2. 收集符合条件的Check方法
        var methodsCollection = classDeclarations
            .Select(static (c, _) => GetEligibleMethods(c));

        // 3. 组合数据并生成代码
        context.RegisterSourceOutput(methodsCollection,
            static (spc, methods) => GenerateDebouncerFields(spc, methods));
    }

    private static bool IsTargetClass(SyntaxNode node)
    {
        // 筛选：静态类声明且名为"DataTracker"
        return node is ClassDeclarationSyntax cds &&
               cds.Identifier.Text == "DataTracker" &&
               cds.Modifiers.Any(SyntaxKind.StaticKeyword);
    }

    private static ClassDeclarationSyntax GetClassDeclaration(GeneratorSyntaxContext context)
    {
        return (ClassDeclarationSyntax)context.Node;
    }

    private static List<MethodDeclarationSyntax> GetEligibleMethods(ClassDeclarationSyntax classDecl)
    {
        return classDecl.Members
            .OfType<MethodDeclarationSyntax>()
            .Where(m => m.Identifier.Text.StartsWith("Check") &&
                        m.Modifiers.Any(SyntaxKind.StaticKeyword) &&
                        m.ParameterList.Parameters.Count == 0 &&
                        m.ReturnType is PredefinedTypeSyntax pts &&
                        pts.Keyword.IsKind(SyntaxKind.VoidKeyword))
            .ToList();
    }

//    private static void GenerateDebouncerFields(SourceProductionContext context, List<MethodDeclarationSyntax> methods)
//    {
//        if (methods.Count == 0)
//            return;

//        var sourceBuilder = new StringBuilder();
//        sourceBuilder.AppendLine(
//"""
//// <auto-generated/>
//// 由DebouncerGenerator自动生成

//using System;

//namespace FMO.Utilities;

//public static partial class DataTracker
//{
//"""
//            );

//        foreach (var method in methods)
//        {
//            var methodName = method.Identifier.Text;
//            var fieldName = methodName + "Invoker";

//            sourceBuilder.AppendLine($"    public static Debouncer {fieldName} {{ get; }} = new Debouncer(DataTracker.{methodName}, 500);");
//        }

//        sourceBuilder.AppendLine("}");


//        context.AddSource("DataTracker.Debouncers.g.cs", sourceBuilder.ToString());
//    }

    private static void GenerateDebouncerFields(SourceProductionContext context, List<MethodDeclarationSyntax> methods)
    {
        if (methods.Count == 0)
            return;

        var sourceBuilder = new StringBuilder();
        foreach (var method in methods)
        {
            var methodName = method.Identifier.Text;
            var fieldName = methodName + "Invoker";

            sourceBuilder.AppendLine($"    public static Debouncer {fieldName} {{ get; }} = new Debouncer(DataTracker.{methodName}, 500);");
        }

        var source =
$$"""
// <auto-generated/>
// 由DebouncerGenerator自动生成

using System;

namespace FMO.Utilities;
 
public static partial class DataTracker
{

{{sourceBuilder.ToString()}}

}
""";




        context.AddSource("DataTracker.Debouncers.g.cs", source);
    }
}